package nettyProtocol.wather;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import nettyProtocol.pojo.Header;
import nettyProtocol.pojo.NettyMessage;
import nettyProtocol.handshakeAndAuthentication.MessageType;

import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

public class HeartBeatReqHandler extends ChannelInboundHandlerAdapter {
    private volatile ScheduledFuture<?> heartBeat;

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        NettyMessage message = (NettyMessage) msg;
        //握手成功，主动发送心跳消息
        if(message.getHeader() != null && message.getHeader().getType() == MessageType.LOGIN_RESP.value){
            heartBeat = ctx.executor().scheduleAtFixedRate(
                    new HeartBeatReqHandler.HeartBeatTask(ctx), 0,5000, TimeUnit.MILLISECONDS
            );
            //统一处理心跳消息
        } else if(message.getHeader() != null && message.getHeader().getType() == MessageType.HEART_RESP.value){
            System.out.println("Client receive server heart beat message : --> " + message);
        } else {
            System.out.println("传给下一条");
            ctx.fireChannelRead(msg);
        }


    }

    private class HeartBeatTask implements Runnable{
        private final ChannelHandlerContext ctx;
        public HeartBeatTask(final  ChannelHandlerContext ctx){
            this.ctx = ctx;
        }
        public void run() {
            NettyMessage heatBeat = buildHeatBeat();
            System.out.println("Client send heart beat message to server : -->" + heatBeat);
            ctx.writeAndFlush(heatBeat);
        }

        private NettyMessage buildHeatBeat() {
            NettyMessage message = new NettyMessage();
            Header header = new Header();
            header.setType(MessageType.HEART_REQ.value);
            message.setHeader(header);
            return message;
        }

    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        if(heartBeat != null){
            heartBeat.cancel(true);
            heartBeat = null;
        }
        ctx.fireExceptionCaught(cause);
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        ctx.flush();
    }
}
